﻿using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using mmCore.Classes;
using mmCore.Common;

namespace mmImdbProvider
{
    public class ImdbEpisodeReader
    {
        private bool _mUpdate = false;
        public event Action<Movie> OnFinished;
        public event Action<Movie, Episode> OnProgress;

        public bool Read(Movie movie)
        {
            return Read(movie, false);
        }

        public bool Read(Movie movie, bool update)
        {
            if(movie == null || movie.Id == null || string.IsNullOrEmpty(movie.Id))
            {
                return false;
            }

            _mUpdate = update;

            var wf = new WebFetch(MovieUtils.GetEpisodesUrl(movie.Id));
            wf.OnFinished += wf_OnFinished;
            wf.Fetch(movie);

            return true;
        }

        private void wf_OnFinished(object sender, FetchEventArgs e)
        {
            const string strReg = 
                "<h3>Season ([\\d]*?), Episode ([\\d]*?): <a href=\"/title/tt\\d{7}/\">([\\d\\D]*?)</a></h3><span class=\"less-emphasis\">" + 
                "Original Air Date&mdash;<strong>([\\d\\D]*?)</strong>";

            var movie = e.Data as Movie;
            if(movie == null)
            {
                return;
            }

            if (!_mUpdate || movie.Episodes == null)
            {
                movie.Episodes = new SObservableCollection<Episode>();
            }

            try
            {
                var rRegex = new Regex(strReg, RegexOptions.Multiline);
                var mMatch = rRegex.Match(e.Result);

                while(mMatch.Success)
                {
                    var ep = new Episode
                    {
                        Season = Int32.Parse(mMatch.Groups[1].Value),
                        EpisodeNo = Int32.Parse(mMatch.Groups[2].Value),
                        Title = HttpUtility.HtmlDecode(mMatch.Groups[3].Value)
                    };

                    DateTime dtDate;
                    ep.AirDate = DateTime.TryParse(mMatch.Groups[4].Value, out dtDate) ? dtDate : DateTime.MinValue;

                    if(!_mUpdate || movie.Episodes.ToList().Where(i => i.EpisodeNo == ep.EpisodeNo && i.Season == ep.Season).Count() == 0)
                    {
                        if (OnProgress != null)
                        {
                            OnProgress(movie, ep);
                        }
                        movie.Episodes.Add(ep);
                    }
                    

                    mMatch = mMatch.NextMatch();
                }

                if(OnFinished != null)
                {
                    OnFinished(movie);
                }
            }
            catch (Exception exc)
            {
                ExceptionManager.ReportError(exc);
                if (OnFinished != null)
                {
                    OnFinished(null);
                }
            }
        }
    }
}
